/** 
 *  @file
 *  @brief   ELAS1 单元 和 ELAS2 单元
 *  @author  kangrongyao
 *  @date    2024.05.30
 *  @version v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "Utility/Algebra/Matrix.h"
#include "DataStructure/Common/Out.h"
#include "DataStructure/Common/Real.h"
#include "../Interface/IElementCalculator.h"

SG_FEMSOLVER_ELEMENT_NAMESPACE_OPEN

class ElementCalculator_DECLSPEC ELAS1Calculator : public SG::FEMSolver::Element::IElementCalculator
{
public:
    ELAS1Calculator () = default;
    virtual ~ELAS1Calculator () = default;

    /**
     * @brief 计算位移坐标系下单元刚度矩阵
     * 
     * @param [in] k 弹簧刚度
     * @param [out] kg 位移坐标系下单元刚度矩阵
     */
    static void ComputeStiffness (const SG::DataStructure::Common::Real k, _OUT SG::Algebra::Matrixd& kg);

    /**
     * @brief 计算单元内力
     * 
     * @param [in] k 弹簧刚度
     * @param [in] elementDisplacement 位移坐标系单元位移
     * @param [out] elementInternalForce 单元内力
     */
    static void ComputeElementInternalForce
    (
    const SG::DataStructure::Common::Real& k,
    const SG::Algebra::Matrixd&            elementDisplacement,
    _OUT SG::DataStructure::Common::Real&  elementInternalForce
    );

    /**
     * @brief    计算单元应变
     * 
     * @param    S 弹簧应力恢复系数
     * @param    elementDisplacement 位移坐标系单元位移
     * @param    elementStrain 单元应变
     * @author   Du Weixing
     * @date     2024.12.18
     */
    static void ComputeElementStrain
    (
    const SG::DataStructure::Common::Real& S,
    const SG::Algebra::Matrixd&            elementDisplacement,
    _OUT SG::DataStructure::Common::Real&  elementStrain
    );

    /**
     * @brief 计算单元应力
     * 
     * @param [in] S 弹簧应力恢复系数
     * @param [in] elementInternalForce 单元内力
     * @param [out] elementStress 单元应力
     */
    static void ComputeElementStress
    (
    const SG::DataStructure::Common::Real& S,
    const SG::DataStructure::Common::Real& elementInternalForce,
    _OUT SG::DataStructure::Common::Real&  elementStress
    );

    virtual void Initialize (SG::DataStructure::FEM::ElementTypes type) override;
    virtual void ComputeElementMatries (const SG::DBManager::DBServiceFactorySP dbServiceFactory) override;
    virtual void DataRecovery (const SG::DBManager::DBServiceFactorySP dbServiceFactory, int subcaseId, SG::DataStructure::Common::Real time, const std::vector<SG::DataStructure::Common::Real>& globalDisplacement) override;
    virtual void ComputeStressStiffness (const SG::DBManager::DBServiceFactorySP dbServiceFactory, int staticSubId) override;

    static ElementCalculatorSP Create () {return std::make_shared<ELAS1Calculator> ();}

private:
    SG::DataStructure::FEM::ElementTypes m_type;
};

SG_FEMSOLVER_ELEMENT_NAMESPACE_CLOSE